package com.sc.nft.service.impl;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.MallMemberEquityDao;
import com.sc.nft.dao.MallMemberEquityUseRecordDao;
import com.sc.nft.entity.MallMemberEquity;
import com.sc.nft.entity.MallMemberEquityTarget;
import com.sc.nft.entity.MallMemberEquityTemplate;
import com.sc.nft.entity.UserInfo;
import com.sc.nft.entity.dto.*;
import com.sc.nft.entity.vo.CanAddAdminMallMemberProductVO;
import com.sc.nft.entity.vo.MallMemberEquityTargetVO;
import com.sc.nft.entity.vo.MallMemberEquityVO;
import com.sc.nft.enums.EquityTypeEnum;
import com.sc.nft.enums.MallMemberEquityTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.MallMemberEquityService;
import com.sc.nft.service.MallMemberEquityTargetService;
import com.sc.nft.service.MallMemberEquityTemplateService;
import com.sc.nft.service.MallMemberService;
import javassist.runtime.DotClass;
import jdk.nashorn.internal.objects.ArrayBufferView;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 商城会员权益 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-03-29
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class MallMemberEquityServiceImpl implements MallMemberEquityService {

    private final MallMemberEquityDao mallMemberEquityDao;
    @Autowired
    MallMemberEquityTemplateService mallMemberEquityTemplateService;
    @Autowired
    MallMemberService mallMemberService;
    private final MallMemberEquityTargetService mallMemberEquityTargetService;

    private final MallMemberEquityUseRecordDao mallMemberEquityUseRecordDao;

    /**
     * 添加商城会员权益
     *
     * @param mallMemberId
     * @param mallMemberEquityVOList
     */
    @Override
    public void add(Long mallMemberId, List<MallMemberEquityVO> mallMemberEquityVOList) {
        for (MallMemberEquityVO mallMemberEquityVO : mallMemberEquityVOList) {
            // 获取商城会员权益模版
            MallMemberEquityTemplate mallMemberEquityTemplate = mallMemberEquityTemplateService.getById(mallMemberEquityVO.getMallMemberEquityTemplateId());
            Assert.notNull(mallMemberEquityTemplate, () -> new GlobalRunTimeException("商城会员权益模版不存在"));
            MallMemberEquity mallMemberEquity = new MallMemberEquity();
            mallMemberEquity.setMallMemberEquityTemplateId(mallMemberEquityVO.getMallMemberEquityTemplateId());
            mallMemberEquity.setMallMemberId(mallMemberId);
            // 根据商城会员权益模版类型设置权益类型
            mallMemberEquity.setEquityType(EquityTypeEnum.getEnumByMallMemberEquityTypeEnum(mallMemberEquityTemplate.getType()));
            mallMemberEquity.insert();
            mallMemberEquityTargetService.add(mallMemberEquity.getId(), mallMemberEquityVO.getMallMemberEquityTargetVOList());
        }
    }

    /**
     * 修改商城会员权益
     *
     * @param mallMemberId
     * @param mallMemberEquityVOList
     */
    @Override
    public void update(Long mallMemberId, List<MallMemberEquityVO> mallMemberEquityVOList) {
        // 获取商城会员权益列表
        List<MallMemberEquity> mallMemberEquityListInDb = getByMallMemberId(mallMemberId);
        Map<Long, MallMemberEquity> mallMemberEquityMap = mallMemberEquityListInDb.stream().collect(Collectors.toMap(MallMemberEquity::getMallMemberEquityTemplateId, mallMemberEquity -> mallMemberEquity, (value1, value2) -> value1));
        for (MallMemberEquityVO mallMemberEquityVO : mallMemberEquityVOList) {
            // 获取商城会员权益模版
            MallMemberEquityTemplate mallMemberEquityTemplate = mallMemberEquityTemplateService.getById(mallMemberEquityVO.getMallMemberEquityTemplateId());
            Assert.notNull(mallMemberEquityTemplate, () -> new GlobalRunTimeException("商城会员权益模版不存在"));
            if (mallMemberEquityMap.containsKey(mallMemberEquityVO.getMallMemberEquityTemplateId())) {
                // 编辑
                MallMemberEquity mallMemberEquity = mallMemberEquityMap.get(mallMemberEquityVO.getMallMemberEquityTemplateId());
                mallMemberEquity.setEquityType(EquityTypeEnum.getEnumByMallMemberEquityTypeEnum(mallMemberEquityTemplate.getType()));
                mallMemberEquity.updateById();
                mallMemberEquityTargetService.update(mallMemberEquity.getId(), mallMemberEquityVO.getMallMemberEquityTargetVOList());
            } else {
                // 新增
                MallMemberEquity mallMemberEquity = new MallMemberEquity();
                mallMemberEquity.setMallMemberEquityTemplateId(mallMemberEquityVO.getMallMemberEquityTemplateId());
                mallMemberEquity.setMallMemberId(mallMemberId);
                mallMemberEquity.setEquityType(EquityTypeEnum.getEnumByMallMemberEquityTypeEnum(mallMemberEquityTemplate.getType()));
                mallMemberEquity.insert();
                mallMemberEquityTargetService.add(mallMemberEquity.getId(), mallMemberEquityVO.getMallMemberEquityTargetVOList());
            }
        }

        List<Long> mallMemberEquityTemplateIds = mallMemberEquityVOList.stream().map(MallMemberEquityVO::getMallMemberEquityTemplateId).collect(Collectors.toList());
        for (MallMemberEquity mallMemberEquity : mallMemberEquityListInDb) {
            if (!mallMemberEquityTemplateIds.contains(mallMemberEquity.getMallMemberEquityTemplateId())) {
                mallMemberEquityDao.removeById(mallMemberEquity.getId());
                // 关联权益也删除
                mallMemberEquityTargetService.remove(mallMemberEquity.getId());
            }
        }
    }

    /**
     * 移除商城会员权益
     *
     * @param mallMemberEquityTemplateId
     * @param mallMemberId
     */
    @Override
    public void remove(Long mallMemberEquityTemplateId, Long mallMemberId) {
        mallMemberEquityDao.remove(mallMemberId, mallMemberEquityTemplateId);
    }

    /**
     * 获取商城会员权益
     *
     * @param mallMemberEquityTemplateId
     * @param mallMemberId
     * @return
     */
    @Override
    public MallMemberEquity get(Long mallMemberEquityTemplateId, Long mallMemberId) {
        return mallMemberEquityDao.get(mallMemberId, mallMemberEquityTemplateId);
    }

    @Override
    public MallMemberEquity get(Long id) {
        return mallMemberEquityDao.getById(id);
    }

    /**
     * 获取商城会员权益列表
     *
     * @param mallMemberId
     * @return
     */
    @Override
    public List<MallMemberEquity> getByMallMemberId(Long mallMemberId) {
        return mallMemberEquityDao.getByMallMemberId(mallMemberId);
    }

    /**
     * 获取商城会员权益列表(app)
     *
     * @param mallMemberId
     * @return
     */
    @Override
    public List<MallMemberEquityPageDTO> getMallMemberEquityPageDTO(Long mallMemberId) {
        return mallMemberEquityDao.getMallMemberEquityPageDTO(mallMemberId);
    }

    /**
     * 获取商城会员权益列表
     *
     * @param mallMemberEquityTemplateId
     * @return
     */
    @Override
    public List<MallMemberEquity> getByMallMemberEquityTemplateId(Long mallMemberEquityTemplateId) {
        return mallMemberEquityDao.getByMallMemberEquityTemplateId(mallMemberEquityTemplateId);
    }

    /**
     * 获取优先购商品列表(app)
     *
     * @param mallMemberId
     * @return
     */
    @Override
    public Page<MallGrabCommoditiesFirstPageDTO> getMallGrabCommoditiesFirstPageDTO(Long mallMemberId, Integer pageNo, Integer pageSize) {
        Page<MallGrabCommoditiesFirstPageDTO> mallGrabCommoditiesFirstPageDTOList = mallMemberEquityDao.getMallGrabCommoditiesFirstPageDTO(mallMemberId, pageNo, pageSize);
        mallGrabCommoditiesFirstPageDTOList.getRecords().forEach(record -> {
            if (StrUtil.isNotBlank(record.getCoverImage())) {
                record.setCoverImage(StrUtil.split(record.getCoverImage(), ",").get(0));
            }
        });
        return mallGrabCommoditiesFirstPageDTOList;
    }

    /**
     * 判断用户会员可抢商品
     *
     * @param user
     * @param activitySpecId
     * @return
     */
    @Override
    public MallMemberCheckHasPreemptionDTO checkHasPreemption(UserInfo user, Long activitySpecId) {
        //判读用户是否有会员权益
        List<UserMallMemberDTO> userMallMemberPageDTOList = mallMemberService.getUserMallMemberPageDTO(user);
        if (CollectionUtils.isEmpty(userMallMemberPageDTOList)) {
            return null;
        }
        //判断该商品是否配置了会员权益
        List<CheckHasPreemptionGetByTargetDTO> checkHasPreemptionGetByTargetDTOList = mallMemberEquityTargetService.checkHasPreemptionGetByTargetId(activitySpecId);
        if (CollectionUtils.isEmpty(checkHasPreemptionGetByTargetDTOList)) {
            return null;
        }
        //对结果集根据根据会员权益进行分组
        Map<Long, List<MallMemberEquityPageDTO>> mallMemberEquityPageDTOMap = userMallMemberPageDTOList.stream().collect(Collectors.toMap(UserMallMemberDTO::getId, UserMallMemberDTO::getMallMemberEquityPageDTOList));
        //获取出对应权益id，和模版id
        List<CheckHasPreemptionRetDataDTO> dataDTOList = new ArrayList<>();
        for (CheckHasPreemptionGetByTargetDTO dto : checkHasPreemptionGetByTargetDTOList) {
            if (mallMemberEquityPageDTOMap.containsKey(dto.getMallMemberId())) {
                List<MallMemberEquityPageDTO> mallMemberEquityPageDTOS = mallMemberEquityPageDTOMap.get(dto.getMallMemberId());
                if (CollectionUtils.isEmpty(mallMemberEquityPageDTOS)) {
                    continue;
                }
                List<MallMemberEquityPageDTO> filterHoldList = mallMemberEquityPageDTOS.stream().filter(MallMemberEquityPageDTO::getIsHold).filter(e -> e.getType().equals(MallMemberEquityTypeEnum.COMMODITY_PRIORITY)).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(filterHoldList)) {
                    continue;
                }
                for (MallMemberEquityPageDTO mallMemberEquityPageDTO : filterHoldList) {
                    if (dto.getMallMemberEquityTemplateId().equals(mallMemberEquityPageDTO.getMallMemberEquityTemplateId())) {
                        CheckHasPreemptionRetDataDTO checkHasPreemptionRetDataDTO = new CheckHasPreemptionRetDataDTO();
                        checkHasPreemptionRetDataDTO.setMallMemberEquityId(dto.getMallMemberEquityId());
                        checkHasPreemptionRetDataDTO.setMallMemberEquityTemplateId(dto.getMallMemberEquityTemplateId());
                        checkHasPreemptionRetDataDTO.setMallMemberEquityTargetId(dto.getId());
                        dataDTOList.add(checkHasPreemptionRetDataDTO);
                    }
                }

            }
        }
        if (CollectionUtils.isEmpty(dataDTOList)) {
            return null;
        }
        //根据权益id和模版id进行操作查询出配置的时间和次数和剩余可用数量
        for (CheckHasPreemptionRetDataDTO dto : dataDTOList) {
            MallMemberEquityTemplate memberEquityTemplate = mallMemberEquityTemplateService.getById(dto.getMallMemberEquityTemplateId());
            Map<String, Date> timeMap = memberEquityTemplate.getReceiveCycle().getTimeMap(DateTime.now());
            if (CollectionUtils.isEmpty(timeMap) || timeMap.get("startTime") == null || timeMap.get("endTime") == null) {
                continue;
            }
            //用户用了多少次权益
            int count = mallMemberEquityUseRecordDao.checkUseCount(dto.getMallMemberEquityId(), user.getId(), timeMap.get("startTime"), timeMap.get("endTime"));
            if (count < memberEquityTemplate.getLimitCountPerUser()) {
                MallMemberCheckHasPreemptionDTO checkHasPreemptionDTO = new MallMemberCheckHasPreemptionDTO();
                checkHasPreemptionDTO.setMallMemberEquityId(dto.getMallMemberEquityTargetId());
                checkHasPreemptionDTO.setPrioritizeTheLeadTime(memberEquityTemplate.getPrioritizeTheLeadTime());
                return checkHasPreemptionDTO;
            }
        }
        return null;
    }

    /**
     * 获取会员权益
     *
     * @param memberId
     * @return
     */
    @Override
    public List<AdminMallMemberEquityDTO> getAdminMallMemberEquityDTO(Long memberId) {
        return mallMemberEquityDao.getAdminMallMemberEquityDTO(memberId);
    }

    /**
     * 获取会员权益模版优惠券（admin）
     *
     * @param memberId
     * @param mallMemberEquityTemplateId
     * @return
     */
    @Override
    public List<AdminMallMemberCouponsDTO> getAdminMallMemberCouponsDTO(Long memberId, Long mallMemberEquityTemplateId) {
        return mallMemberEquityDao.getAdminMallMemberCouponsDTO(memberId, mallMemberEquityTemplateId);
    }

    /**
     * 获取会员权益模版商品（admin）
     *
     * @param memberId
     * @param mallMemberEquityTemplateId
     * @return
     */
    @Override
    public List<AdminMallMemberProductDTO> getAdminMallMemberProductDTO(Long memberId, Long mallMemberEquityTemplateId) {
        List<AdminMallMemberProductDTO> adminMallMemberProductDTO = mallMemberEquityDao.getAdminMallMemberProductDTO(memberId, mallMemberEquityTemplateId);
        for (AdminMallMemberProductDTO record : adminMallMemberProductDTO) {
            if (StrUtil.isNotBlank(record.getCoverImage())) {
                record.setCoverImage(StrUtil.split(record.getCoverImage(), ",").get(0));
            }
        }
        return adminMallMemberProductDTO;
    }

    /**
     * 获取可添加至会员权益模版商品列表
     *
     * @param canAddAdminMallMemberProductVO
     * @return
     */
    @Override
    public Page<AdminMallMemberProductDTO> getCanAddAdminMallMemberProductDTO(CanAddAdminMallMemberProductVO canAddAdminMallMemberProductVO) {
        Page<AdminMallMemberProductDTO> canAddAdminMallMemberProductDTO = mallMemberEquityDao.getCanAddAdminMallMemberProductDTO(canAddAdminMallMemberProductVO.getProductName(), canAddAdminMallMemberProductVO.getPageNo(), canAddAdminMallMemberProductVO.getPageSize());
        for (AdminMallMemberProductDTO record : canAddAdminMallMemberProductDTO.getRecords()) {
            if (StrUtil.isNotBlank(record.getCoverImage())) {
                record.setCoverImage(StrUtil.split(record.getCoverImage(), ",").get(0));
            }
            List<AdminMallMemberProductSpecsDTO> canAddAdminMallMemberProductSpecsDTO = mallMemberEquityDao.getCanAddAdminMallMemberProductSpecsDTO(record.getActivityId());
            record.setSpecsList(canAddAdminMallMemberProductSpecsDTO);
        }
        return canAddAdminMallMemberProductDTO;
    }
}
